/******************************************************************************
 *
 *  wav2aac.c
 *
 *  Created on: 2012-4-6
 *      Author: Michael
 *       Email: zhongchao.ustc@gmail.com
 *
 *  Copyright (c) Michael Chao Zhong
 *
 *	Depend:
 *		FAAC-1.28
 *
 *	Compile:
 *		g++ wav2aac.c -L/usr/local/lib -lfaac -I/usr/local/include -o wav2faac
 *
 *	Run:
 *		./wav in.wav out.aac
 *
 *****************************************************************************/

#include <faac.h>
#include <stdio.h>

typedef unsigned long	ULONG;
typedef unsigned int	UINT;
typedef unsigned char	BYTE;
typedef char			_TCHAR;

int main(int argc, _TCHAR* argv[])
{
	ULONG nSampleRate = 11025; //22050;
	UINT nChannels = 1;
	UINT nPCMBitSize = 16;
	ULONG nInputSamples = 0;
	ULONG nMaxOutputBytes = 0;

	int nRet;
	faacEncHandle hEncoder;
	faacEncConfigurationPtr pConfiguration;

	int nBytesRead;
	int nPCMBufferSize;
	BYTE* pbPCMBuffer;
	BYTE* pbAACBuffer;

	FILE* fpIn; // WAV file for input
	FILE* fpOut; // AAC file for output

	if (argc != 3)
	{
		printf("[ERROR] Two arguments needed: in.wav out.aac");
		return -1;
	}

	fpIn = fopen(argv[1], "rb");
	fpOut = fopen(argv[2], "wb");

 	// (1) Open FAAC decoder
	hEncoder = faacEncOpen(nSampleRate, nChannels, &nInputSamples, &nMaxOutputBytes);
	if(hEncoder == NULL)
	{
		printf("[ERROR] Failed to call faacEncOpen()\n");
		return -1;
	}

	nPCMBufferSize = nInputSamples * nPCMBitSize / 8;
	pbPCMBuffer = new BYTE [nPCMBufferSize];
	pbAACBuffer = new BYTE [nMaxOutputBytes];

 	// (2.1) Get current encoding configuration
	pConfiguration = faacEncGetCurrentConfiguration(hEncoder);
	pConfiguration->inputFormat = FAAC_INPUT_16BIT;

	// (2.2) Set encoding configuration
	nRet = faacEncSetConfiguration(hEncoder, pConfiguration);

	for(int i=0; 1; i++)
	{
		nBytesRead = fread(pbPCMBuffer, 1, nPCMBufferSize, fpIn);

		nInputSamples = nBytesRead / (nPCMBitSize / 8);

	 	// (3) Encode
		nRet = faacEncEncode(
		hEncoder, (int*) pbPCMBuffer, nInputSamples, pbAACBuffer, nMaxOutputBytes);

		fwrite(pbAACBuffer, 1, nRet, fpOut);

		printf("%d: faacEncEncode returns %d\n", i, nRet);

		if(nBytesRead <= 0)
		{
			break;
		}
	}

	// (4) Close FAAC decoder
	nRet = faacEncClose(hEncoder);

	delete[] pbPCMBuffer;
	delete[] pbAACBuffer;
	fclose(fpIn);
	fclose(fpOut);

	getchar();

	return 0;
}
